/**
 * @file
 * @author Ivan Babushkin (jogrms@gmail.com)
 * @date 10.06.2010
 */

#include <mainwindow.h>
#include <QCloseEvent>
#include <qodefault.h>
#include <QtWebKit/QWebView>
#include <QtWebKit/QWebPage>
#include <QtWebKit/QWebFrame>
#include <QFile>
#include <QTextStream>
#include <qorangeapp.h>
#include <QColor>
#include <QDebug>
#include <QWheelEvent>

MainWindow::MainWindow(QWidget *parent, Qt::WFlags flags) :QMainWindow(parent, flags) {

	//ui.setupUi(this);

	commandOpen = QString(COMMAND_OPEN);
	commandTabOpen = QString(COMMAND_TABOPEN);
	commandTabClose = QString(COMMAND_TABCLOSE);
	commandExit = QString(COMMAND_EXIT);

	actionOpen = new QAction(this);
	actionTabOpen = new QAction(this);
	actionTabNew = new QAction(this);
	actionTabNext = new QAction(this);
	actionTabClose = new QAction(this);
	actionEsc = new QAction(this);
//	actionExit = new QAction(this);

	actionTabNew->setShortcut(QKeySequence::AddTab);
	actionTabNext->setShortcut(QKeySequence::NextChild);
	actionTabClose->setShortcut(QKeySequence::Close);
	actionEsc->setShortcut(QKeySequence(Qt::Key_Escape));
//	actionExit->setShortcut(QKeySequence(Qt::Key_Q));
	//actionTabOpen->setShortcut();
	
	connect(actionTabNew, SIGNAL(triggered()), this, SLOT(runTabNew()));
	connect(actionTabNext, SIGNAL(triggered()), this, SLOT(runTabNext()));
	connect(actionTabClose, SIGNAL(triggered()), this, SLOT(runTabClose()));
	connect(actionEsc, SIGNAL(triggered()), this, SLOT(runEsc()));
//	connect(actionExit, SIGNAL(triggered()), this, SLOT(runExit()));

	addAction(actionTabNew);
	addAction(actionTabNext);
	addAction(actionTabClose);
	addAction(actionEsc);
//	addAction(actionExit);

	cmdEdit = new CmdEdit(this);
	connect(cmdEdit, SIGNAL(returnPressed()), this, SLOT(cmdEditReturnPressed()));

	infoButton = new ToolButton(this);

	init();
}

MainWindow::~MainWindow() {
	cmdEdit->saveHistory("cmdhistory");
	webViews.clear();
	pageButtons.clear();
	delete cmdEdit;
	delete infoButton;
}

void MainWindow::init() {
	settings.cmdEditHeight = 18;
	settings.cmdEditIndent = 50;
	settings.cmdEditFrame = false;
	settings.cmdEditBgColor = QColor(255, 200, 100);
	settings.cmdEditHistory = 5;
	settings.webViewVScroll = Qt::ScrollBarAlwaysOff;
	settings.webViewHScroll = Qt::ScrollBarAlwaysOff;

	lastUrl.clear();

	infoButton->applySettings(&settings);
	cmdEdit->applySettings(&settings);
	cmdEdit->loadHistory("cmdhistory");

	QWebSettings::globalSettings()->setAttribute(QWebSettings::PluginsEnabled, true);
	QWebSettings::globalSettings()->setAttribute(QWebSettings::JavascriptEnabled, true);

	setWindowTitle(QString("Start Page - ") + QString(APP_NAME));
	webViews.append(new WebView(&settings, this));
	pageButtons.append(new QPushButton());
	if (webViews.isEmpty()) {
		return;
	}
	currentPage = 0;
	openFile(DEFAULT_HTML);
	webViews[currentPage]->setFocusPolicy(Qt::StrongFocus);
//	pageActionNewTab = webViews[currentPage]->pageAction(QWebPage::OpenLinkInNewWindow);
//	connect(pageActionNewTab, SIGNAL(triggered()), this, SLOT(runPageNewTab()));

	webViews[currentPage]->show();
	cmdEdit->hide();
	infoButton->raise();
	infoButton->hide();
	cmdEdit->stackUnder(infoButton);
	webViews[currentPage]->stackUnder(cmdEdit);
}

void MainWindow::resizeEvent(QResizeEvent *event) {
	webViews[currentPage]->resize(width(), height());
	cmdEdit->resize(event->size().width() - 2 * settings.cmdEditIndent,
			settings.cmdEditHeight);
	cmdEdit->move(settings.cmdEditIndent, event->size().height() - settings.cmdEditHeight - 2);
	infoButton->move(5, event->size().height() - 22);
}

void MainWindow::closeEvent(QCloseEvent *event) {
	cmdEdit->saveHistory("cmdhistory");
}

void MainWindow::keyPressEvent(QKeyEvent *event) {
	switch (event->key()) {
		case ':':
			showCmdEdit(":");
			break;

		case 'O':
			showCmdEdit(":o ");
			break;

		case 'T':
			showCmdEdit(":t ");
			break;

		case Qt::Key_Q:
			showCmdEdit(":q ");
			break;

		case Qt::Key_U:
			if (!lastUrl.isEmpty()) {
				openUrlNewTab(lastUrl, true);
				lastUrl.clear();
			}
			break;

		case Qt::Key_D:
			runTabClose();
			break;

		case Qt::Key_Up:
			currentWebView()->page()->mainFrame()->scroll(0, -20);
			break;

		case Qt::Key_Down:
			currentWebView()->page()->mainFrame()->scroll(0, 20);
			break;

		case Qt::Key_Left:
			currentWebView()->page()->mainFrame()->scroll(-20, 0);
			break;

		case Qt::Key_Right:
			currentWebView()->page()->mainFrame()->scroll(20, 0);
			break;
	}
	QMainWindow::keyPressEvent(event);
}

void MainWindow::wheelEvent(QWheelEvent *event) {
/*	if (event->orientation() == Qt::Vertical) {
		currentWebView()->page()->mainFrame()->scroll(0, event->delta());
	}
	else {
		currentWebView()->page()->mainFrame()->scroll(event->delta(), 0);
	}
	event->accept();
	*/
}

struct QOSettings MainWindow::getSettings() {
	return settings;
}

void MainWindow::showCmdEdit(QString cmd) {
	cmdEdit->setText(cmd);  // dont change this order!
	cmdEdit->show();        // cause cmdEdit saves its text on show event.
	cmdEdit->raise();
	webViews[currentPage]->stackUnder(infoButton);
	cmdEdit->setFocus();
}

void MainWindow::openFile(QString fileName, int page) {
	QFile in(fileName);
	if (!in.open(QIODevice::ReadOnly | QIODevice::Text)) {
		return;
	}
	QTextStream stream(&in);
	webViews[page]->setHtml(stream.readAll());
}

void MainWindow::openFile(QString fileName) {
	openFile(fileName, currentPage);
}

void MainWindow::openUrl(QString url, int page) {
	while (url.startsWith(" ")) {
		url.remove(0, 1);
	}
	if (url == "") {
		openFile(DEFAULT_HTML, page);
		return;
	}
	if (!url.contains("://", Qt::CaseSensitive)) {
		url = "http://" + url;
	}
	webViews[page]->load(url);
}

void MainWindow::openUrl(QUrl url, int page) {
	if (url.toString() == "about:blank") {
		openFile(DEFAULT_HTML, page);
	}
	else {
		webViews[page]->load(url);
	}
}

void MainWindow::processCmd(QString cmdLine) {
	QString tempCmdLine;
	while (cmdLine.startsWith(" ")) {
		cmdLine.remove(0, 1);
	}
	while (cmdLine.endsWith(" ")) {
		cmdLine.remove(cmdLine.count() - 1, 1);
	}

	if (cmdLine.startsWith(":")) {
		cmdLine.remove(0, 1);
		
		tempCmdLine = cmdLine;
		if (tempCmdLine.startsWith(commandOpen)) {
			tempCmdLine.remove(0, commandOpen.length());
			if (tempCmdLine == "") {
				openUrl("", currentPage);
			}
			else if (tempCmdLine.startsWith(" ")) {
				openUrl(tempCmdLine, currentPage);
			}
		}
		tempCmdLine = cmdLine;
		if (tempCmdLine.startsWith(commandTabOpen)) {
			tempCmdLine.remove(0, commandTabOpen.length());
			if (tempCmdLine == "") {
				openUrlNewTab("", true);
			}
			else if (tempCmdLine.startsWith(" ")) {
				openUrlNewTab(tempCmdLine, true);
			}
		}
		tempCmdLine = cmdLine;
		if (tempCmdLine == commandTabClose) {
			runTabClose();
		}
		tempCmdLine = cmdLine;
		if (tempCmdLine == commandExit) {
			runExit();
		}
		
		return;
	}
}

void MainWindow::openUrlNewTab(QString url, bool switchTo) {
	webViews.append(new WebView(&settings, this));
//	connect(webViews.takeLast()->pageAction(QWebPage::OpenLinkInNewWindow),
//			SIGNAL(triggered()), this, SLOT(runPageNewTab()));
	openUrl(url, webViews.count() - 1);
	if (!switchTo) {
		return;
	}
	webViews[currentPage]->hide();
	currentPage = webViews.count() - 1;
	webViews[currentPage]->resize(width(), height());
	webViews[currentPage]->show();
	currentWebView()->stackUnder(infoButton);
	webViews[currentPage]->setFocus();
	infoButton->turnProgress(currentWebView()->getProgress());
//	pageActionNewTab = webViews[currentPage]->pageAction(QWebPage::OpenLinkInNewWindow);
}

void MainWindow::openUrlNewTab(QUrl url, bool switchTo) {
	webViews.append(new WebView(&settings, this));
//	connect(webViews.takeLast()->pageAction(QWebPage::OpenLinkInNewWindow),
//			SIGNAL(triggered()), this, SLOT(runPageNewTab()));
	openUrl(url, webViews.count() - 1);
	if (!switchTo) {
		return;
	}
	webViews[currentPage]->hide();
	currentPage = webViews.count() - 1;
	webViews[currentPage]->resize(width(), height());
	webViews[currentPage]->show();
	webViews[currentPage]->setFocus();
	infoButton->turnProgress(currentWebView()->getProgress());
//	pageActionNewTab = webViews[currentPage]->pageAction(QWebPage::OpenLinkInNewWindow);
}

WebView* MainWindow::currentWebView() {
	return webViews[currentPage];
}

WebView* MainWindow::createNewTab() {
	openUrlNewTab("none", false);
	return webViews[webViews.count() - 1];
}

// slots

void MainWindow::loadStarted() {

	if (sender() != currentWebView()) {
		return;
	}
	infoButton->turnStarted();
}

void MainWindow::loadProgress(int progress) {
	if (sender() != currentWebView()) {
		return;
	}
	infoButton->turnProgress(progress);
}

void MainWindow::loadFinished(bool ok) {
	if (sender() != currentWebView()) {
		return;
	}
	infoButton->turnFinished(ok);
}

void MainWindow::runExit() {
//	QOrangeApp::instance()->quit();

	close();
}

void MainWindow::runEsc() {
	cmdEdit->hide();
	setFocus();
}

void MainWindow::cmdEditReturnPressed()  {
	cmdEdit->hide();
	webViews[currentPage]->setFocus();
	processCmd(cmdEdit->text());
}

void MainWindow::runTabNew() {
	openUrlNewTab("", true);
}

void MainWindow::runTabNext() {
	if (webViews.count() == 1) {
		return;
	}
	webViews[currentPage]->hide();
	if (currentPage == webViews.count() - 1) {
		currentPage = 0;
	}
	else {
		currentPage++;
	}
	webViews[currentPage]->resize(width(), height());
//	pageActionNewTab = webViews[currentPage]->pageAction(QWebPage::OpenLinkInNewWindow);
	webViews[currentPage]->show();
	webViews[currentPage]->setFocus();
	infoButton->turnProgress(currentWebView()->getProgress());
}

void MainWindow::runTabClose() {
	if ((webViews.count() > 1) || (currentWebView()->url().toString() != "about:blank")) {
		lastUrl = currentWebView()->url();
	}
	if (webViews.count() == 1) {
		openFile(DEFAULT_HTML, 0);
		return;
	}
	webViews[currentPage]->hide();
	webViews.removeAt(currentPage);
	webViews[0]->resize(width(), height());
	webViews[0]->show();
	currentPage = 0;
	webViews[currentPage]->setFocus();
	infoButton->turnProgress(currentWebView()->getProgress());
//	pageActionNewTab = webViews[currentPage]->pageAction(QWebPage::OpenLinkInNewWindow);
}
